package org.mobai.flow.strategy.context;

import cn.hutool.core.util.ObjectUtil;
import jakarta.annotation.Resource;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.builder.AbstractFlowNodeBuilder;
import org.mobai.flow.enums.BpmnEnum;
import org.mobai.flow.pojo.bpmn.Node;
import org.mobai.flow.pojo.bpmn.node.EndEvent;
import org.mobai.flow.pojo.bpmn.node.ExclusiveGateWay;
import org.mobai.flow.pojo.bpmn.node.StartEvent;
import org.mobai.flow.strategy.BpmnStrategy;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author hyk
 */
@Component
public class BpmnBuildContext<T extends Node> {
    @Resource
    @Lazy
    private Map<String, BpmnStrategy<T>> bpmnStrategyMap;



    public AbstractFlowNodeBuilder buildBpmn(AbstractFlowNodeBuilder flowNodeBuilder, Node node, Map<String, String> nodeMap) {
        nodeMap.put(node.getId(), node.getPid());
        if (!(node instanceof EndEvent || node instanceof StartEvent || node instanceof ExclusiveGateWay)) {
            if (ObjectUtil.isNotEmpty(nodeMap.get("lastId"))) {
                Optional.ofNullable(node.getOperations()).ifPresent(operations -> {
                    if (ObjectUtil.isEmpty(operations.getBackNodeId())) {
                        operations.setBackNodeId(nodeMap.get("lastId"));
                    } else {
                        operations.setBackNodeId(nodeMap.get(operations.getBackNodeId()));
                    }
                });
            }
            nodeMap.put("lastId", node.getId());

        }

        return bpmnStrategyMap.get(BpmnEnum.getBpmnStrategy(String.valueOf(node.getType()))).build(flowNodeBuilder, (T) node, nodeMap);
    }

    public BpmnModelInstance buildBpmnModelInstance(Node node) {
        return buildBpmn(Bpmn.createExecutableProcess().startEvent(), node, new HashMap<>()).done();
    }

}
